home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / misc / mouse_ta.z / mouse_ta / mouse / mouse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-01  |  9.6 KB  |  354 lines

  1. /* provided by hlu, modified slightly by obz */
  2. /*
  3.  * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
  4.  *
  5.  * Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both that
  8.  * copyright notice and this permission notice appear in supporting
  9.  * documentation, and that the name of Thomas Roell not be used in
  10.  * advertising or publicity pertaining to distribution of the software without
  11.  * specific, written prior permission.  Thomas Roell makes no representations
  12.  * about the suitability of this software for any purpose.  It is provided
  13.  * "as is" without express or implied warranty.
  14.  *
  15.  * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  16.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  17.  * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  18.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  19.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  20.  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  21.  * PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * $Header: /proj/X11/mit/server/ddx/x386/RCS/x386Io.c,v 1.2 1991/06/27 00:01:38 root Exp $
  24.  */
  25.  
  26. #define NEED_EVENTS
  27. #if 0
  28. #include "X.h"
  29. #include "Xproto.h"
  30. #include "inputstr.h"
  31. #include "scrnintstr.h"
  32.  
  33. #include "compiler.h"
  34.  
  35. #include "x386Procs.h"
  36. #include "x386OSD.h"
  37. #include "atKeynames.h"
  38. #else
  39. #include "mouse.h"
  40. #endif
  41.  
  42. static void
  43. Error (const char *str)
  44. {
  45.   fprintf (stderr, "%s\n", str);
  46. }
  47.  
  48. static void
  49. x386PostMseEvent (int button, int dx, int dy)
  50. {
  51.   fprintf (stderr, "button: %d, dx: %d, dy: %d\n", button, dx, dy);
  52. }
  53.  
  54. static void
  55. x386SetSpeed(old, new, cflag)
  56.      int old, new;
  57.      unsigned short cflag;
  58. {
  59.   struct termio  tty;
  60.   char           *c;
  61.  
  62.   (void) ioctl(x386Info.mseFd, TCGETA, &tty);
  63.   tty.c_iflag = IGNBRK | IGNPAR ;     
  64.   tty.c_oflag = 0;           
  65.   tty.c_lflag = 0;
  66.   tty.c_line = 0;
  67.   tty.c_cc[VTIME]=0; 
  68.   tty.c_cc[VMIN]=1;
  69.   
  70.   switch (old) {
  71.   case 9600:  tty.c_cflag = cflag | B9600;  break;
  72.   case 4800:  tty.c_cflag = cflag | B4800;  break;
  73.   case 2400:  tty.c_cflag = cflag | B2400;  break;
  74.   case 1200:
  75.   default:    tty.c_cflag = cflag | B1200;  break;
  76.   }
  77.   (void) ioctl(x386Info.mseFd, TCSETAW, &tty);  
  78.   
  79.   switch(new) {
  80.   case 9600:  c = "*q";  tty.c_cflag = cflag | B9600;  break;
  81.   case 4800:  c = "*p";  tty.c_cflag = cflag | B4800;  break;
  82.   case 2400:  c = "*o";  tty.c_cflag = cflag | B2400;  break;
  83.   case 1200:
  84.   default:    c = "*n";  tty.c_cflag = cflag | B1200;  break;
  85.   }
  86.  
  87.   write(x386Info.mseFd, c, 2);  
  88.   usleep(100000);
  89.  
  90.   (void) ioctl(x386Info.mseFd, TCSETAW, &tty);  
  91. #ifdef TCMOUSE
  92.   (void) ioctl(x386Info.mseFd, TCMOUSE, 1);  
  93. #endif
  94. }
  95.  
  96.  
  97. /*
  98.  * x386MseProc --
  99.  *      Handle the initialization, etc. of a mouse
  100.  */
  101.  
  102. int
  103. x386MseProc(what)
  104.      int        what;
  105. {
  106.   unchar                map[4];
  107.  
  108.   static unsigned short cflag[5] =
  109.     {
  110. #ifdef linux_hack /* not needed with patch3 - server doesn't do this! */
  111.       (CS7 | ISTRIP          | CREAD | CLOCAL | HUPCL ),   /* MicroSoft */
  112. #else
  113.       (CS7              | CREAD | CLOCAL | HUPCL ),   /* MicroSoft */
  114. #endif
  115.       (CS8 | CSTOPB          | CREAD | CLOCAL | HUPCL ),   /* MouseSystems */
  116.       (CS8 | PARENB | PARODD | CREAD | CLOCAL | HUPCL ),   /* MMSeries */
  117.       (CS8 | CSTOPB          | CREAD | CLOCAL | HUPCL ),   /* Logitech */
  118.       0,                                                   /* BusMouse */
  119.     };
  120.   
  121.   switch (what)
  122.     {
  123.     case DEVICE_INIT: 
  124.       map[1] = 3;
  125.       map[2] = 2;
  126.       map[3] = 1;
  127.       break;
  128.       
  129.     case DEVICE_ON:
  130.       if ((x386Info.mseFd = open(x386Info.mseDevice, O_RDWR | O_NDELAY)) < 0)
  131.     {
  132.       Error ("Cannot open mouse");
  133.       return (!Success);
  134.     }
  135.  
  136.       if (x386Info.mseType != P_BM) 
  137.     {
  138.       x386SetSpeed(9600, x386Info.baudRate, cflag[x386Info.mseType]);
  139.       x386SetSpeed(4800, x386Info.baudRate, cflag[x386Info.mseType]);
  140.       x386SetSpeed(2400, x386Info.baudRate, cflag[x386Info.mseType]);
  141.       x386SetSpeed(1200, x386Info.baudRate, cflag[x386Info.mseType]);
  142.  
  143.       if (x386Info.mseType == P_LOGI)
  144.         {
  145.           write(x386Info.mseFd, "S", 1);
  146.           x386SetSpeed(x386Info.baudRate, x386Info.baudRate, cflag[P_MM]);
  147.         }
  148.  
  149.       if      (x386Info.sampleRate <=   0)  write(x386Info.mseFd, "O", 1);
  150.       else if (x386Info.sampleRate <=  15)  write(x386Info.mseFd, "J", 1);
  151.       else if (x386Info.sampleRate <=  27)  write(x386Info.mseFd, "K", 1);
  152.       else if (x386Info.sampleRate <=  42)  write(x386Info.mseFd, "L", 1);
  153.       else if (x386Info.sampleRate <=  60)  write(x386Info.mseFd, "R", 1);
  154.       else if (x386Info.sampleRate <=  85)  write(x386Info.mseFd, "M", 1);
  155.       else if (x386Info.sampleRate <= 125)  write(x386Info.mseFd, "Q", 1);
  156.       else                                  write(x386Info.mseFd, "N", 1);
  157.     }
  158.       
  159.       x386Info.lastButtons = 0;
  160.       x386Info.emulateState = 0;
  161.       break;
  162.       
  163.     case DEVICE_OFF:
  164.     case DEVICE_CLOSE:
  165.       if (x386Info.mseType == P_LOGI)
  166.     {
  167.       write(x386Info.mseFd, "U", 1);
  168.       x386SetSpeed(x386Info.baudRate, 1200, cflag[P_LOGI]);
  169.     }
  170.       close(x386Info.mseFd);
  171.       break;
  172.       
  173.     }
  174.  
  175.   return Success;
  176. }
  177.  
  178.  
  179.  
  180. /*
  181.  * x386MseEvents --
  182.  *      Read the new events from the device, and pass them to the eventhandler.
  183.  */
  184.  
  185. void
  186. x386MseEvents()
  187. {
  188.   unchar               rBuf[64];
  189.   int                  i,nBytes, buttons, dx, dy;
  190.   static int           pBufP = 0;
  191.   static unsigned char pBuf[8];
  192.  
  193.   static unsigned char proto[5][5] = {
  194.     /*  hd_mask hd_id   dp_mask dp_id   nobytes */
  195.     {     0x40,    0x40,    0x40,    0x00,    3     },  /* MicroSoft */
  196.     {    0xf8,    0x80,    0x00,    0x00,    5    },  /* MouseSystems */
  197.     {    0xe0,    0x80,    0x80,    0x00,    3    },  /* MMSeries */
  198.     {    0xe0,    0x80,    0x80,    0x00,    3    },  /* Logitech */
  199.     {    0xf8,    0x80,    0x00,    0x00,    5    },  /* BusMouse */
  200.   };
  201.   
  202.   if (!(nBytes = read(x386Info.mseFd, (char *)rBuf, sizeof(rBuf)))) return;
  203.  
  204.   for ( i=0; i < nBytes; i++) {
  205.     /*
  206.      * Hack for resyncing: We check here for a package that is:
  207.      *  a) illegal (detected by wrong data-package header)
  208.      *  b) invalid (0x80 == -128 and that might be wrong for MouseSystems)
  209.      *  c) bad header-package
  210.      *
  211.      * NOTE: b) is a voilation of the MouseSystems-Protocol, since values of
  212.      *       -128 are allowed, but since they are very seldom we can easily
  213.      *       use them as package-header with no button pressed.
  214.      */
  215.     if (pBufP != 0 && 
  216.     ((rBuf[i] & proto[x386Info.mseType][2]) != proto[x386Info.mseType][3]
  217.      || rBuf[i] == 0x80))
  218.       {
  219.     pBufP = 0;          /* skip package */
  220.       }
  221.  
  222.     if (pBufP == 0 &&
  223.     (rBuf[i] & proto[x386Info.mseType][0]) != proto[x386Info.mseType][1])
  224.       {
  225.     /*
  226.      * Hack for Logitech MouseMan Mouse - Middle button
  227.      *
  228.      * Unfortunately this mouse has variable length packets: the standard
  229.      * Microsoft 3 byte packet plus an optional 4th byte whenever the
  230.      * middle button status changes.
  231.      *
  232.      * We have already processed the standard packet with the movement
  233.      * and button info.  Now post an event message with the old status
  234.      * of the left and right buttons and the updated middle button.
  235.      */
  236.     if (x386Info.mseType == P_MS && (rBuf[i] == 0x20 || rBuf[i] == 0))
  237.       {
  238.         buttons = ((int)(rBuf[i] & 0x20) >> 4)
  239.           | (x386Info.lastButtons & 0x05);
  240.         x386PostMseEvent(buttons, 0, 0);
  241.       }
  242.  
  243.     continue;            /* skip package */
  244.       }
  245.  
  246.  
  247.     pBuf[pBufP++] = rBuf[i];
  248.     if (pBufP != proto[x386Info.mseType][4]) continue;
  249.  
  250.     /*
  251.      * assembly full package
  252.      */
  253.     switch(x386Info.mseType) {
  254.       
  255.     case P_MS:              /* Mircosoft */
  256.       buttons = (x386Info.lastButtons & 2)
  257.     | ((int)(pBuf[0] & 0x20) >> 3)
  258.       | ((int)(pBuf[0] & 0x10) >> 4);
  259.       dx = (char)(((pBuf[0] & 0x03) << 6) | (pBuf[1] & 0x3F));
  260.       dy = (char)(((pBuf[0] & 0x0C) << 4) | (pBuf[2] & 0x3F));
  261.       break;
  262.       
  263.     case P_MSC:             /* Mouse Systems Corp */
  264.       buttons = (~pBuf[0]) & 0x07;
  265.       dx =    (char)(pBuf[1]) + (char)(pBuf[3]);
  266.       dy = - ((char)(pBuf[2]) + (char)(pBuf[4]));
  267.       break;
  268.       
  269.     case P_MM:              /* MM Series */
  270.     case P_LOGI:            /* Logitech Mice */
  271.       buttons = pBuf[0] & 0x07;
  272.       dx = (pBuf[0] & 0x10) ?   pBuf[1] : - pBuf[1];
  273.       dy = (pBuf[0] & 0x08) ? - pBuf[2] :   pBuf[2];
  274.       break;
  275.       
  276.     case P_BM:              /* BusMouse */
  277.       buttons = (~pBuf[0]) & 0x07;
  278.       dx =   (char)pBuf[1];
  279.       dy = - (char)pBuf[2];
  280.       break;
  281.     }
  282.  
  283.     x386PostMseEvent(buttons, dx, dy);
  284.     pBufP = 0;
  285.   }
  286. }
  287.  
  288. void
  289. x386MseConfig (char *dev, int type)
  290. {
  291.   x386Info.mseType = type;
  292.   x386Info.mseDevice = dev;
  293.   x386Info.sampleRate = 150;
  294.   x386Info.emulate3Buttons = FALSE;
  295. }
  296.  
  297. int stop = FALSE;
  298.  
  299. void
  300. stopit(int foo)
  301. {
  302.     stop = TRUE;
  303. }
  304.  
  305. main (int argc, char **argv)
  306. {
  307.   int i = 0;
  308.   char *str, *dev;
  309.  
  310.   if (argc != 3) {
  311.     fprintf (stderr, "Usage: %s [Microsoft|MouseSystem|MMseries|Logitech] device\n", argv [0]);
  312.     exit (1);
  313.   }
  314.  
  315.   i = P_MS;
  316.   if (!strcasecmp (argv [1], "Microsoft")) i = P_MS;
  317.   if (!strcasecmp (argv [1], "MouseSystem")) i = P_MSC;
  318.   if (!strcasecmp (argv [1], "MMseries")) i = P_MM;
  319.   if (!strcasecmp (argv [1], "Logitech")) i = P_LOGI;
  320.  
  321.   dev = argv[2];
  322.  
  323.   switch (i) {
  324.   case P_MS:
  325.     str = "Microsoft";
  326.     break;
  327.   case P_MSC:
  328.     str = "MouseSystem";
  329.     break;
  330.   case P_MM:
  331.     str= "MMseries";
  332.     break;
  333.   case P_LOGI:
  334.     str = "Logitech";
  335.     break;
  336.   }
  337.   fprintf (stderr, "You are testing %s on %s.\n", str, dev);
  338.   x386MseConfig (dev, i);
  339.  
  340.   x386MseProc(DEVICE_INIT);
  341.   x386MseProc(DEVICE_ON);
  342. /*   outb (0x03fb, 0x03); */
  343.  
  344.   signal(SIGINT, stopit);
  345.   fprintf(stderr, "Play with the mouse - hit ctrl-c to stop\n");
  346.   for (;;) {
  347.     if (stop)
  348.         break;
  349.     x386MseEvents();
  350.   }
  351.   x386MseProc(DEVICE_CLOSE);
  352.   fprintf(stderr, "finished.\n");
  353. }
  354.